package com.dly.blog.run;

import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import com.dly.blog.properties.CodeGenProperties;
import lombok.AllArgsConstructor;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@EnableConfigurationProperties(CodeGenProperties.class)
@AllArgsConstructor
public class CodeGenRun implements ApplicationRunner {

    private final CodeGenProperties codeGenProperties;

    @Override
    public void run(ApplicationArguments args) throws Exception {

        FastAutoGenerator.create(codeGenProperties.getDatasource().getUrl(),
                        codeGenProperties.getDatasource().getUsername(),
                        codeGenProperties.getDatasource().getPassword())
                //全局配置
                .globalConfig(builder ->
                                builder.author(codeGenProperties.getBaseConfig().getAuthor())
                                        .enableSpringdoc()
                                        .dateType(DateType.TIME_PACK)
                                        .commentDate("yyyy-MM-dd HH:mm:ss")
                        //包配置
                ).packageConfig(builder ->
                                builder.parent(codeGenProperties.getBaseConfig().getPage())
                                        //配置包名
                                        .entity("domain")
                                        .pathInfo(codeGenProperties.getBaseConfig().getMaps())
                        //匹配模式配置
                ).strategyConfig(builder ->
                        builder.addInclude(codeGenProperties.getBaseConfig().getTableNames())
                                .addTablePrefix(codeGenProperties.getBaseConfig().getTablePrefix())
                                //处理实体类
                                .entityBuilder()
                                .addIgnoreColumns("create_time", "update_time", "create_user", "update_user", "deleted")
                                .enableLombok()
                                .idType(IdType.ASSIGN_ID)
                                .enableTableFieldAnnotation()
                                .superClass("com.dly.blog.meta.MetaObject")
                                .enableFileOverride()

                                //处理service接口
                                .serviceBuilder()
                                .convertServiceFileName(serviceName -> serviceName + "Service")
                                .enableFileOverride()

                                //处理controller
                                .controllerBuilder()
                                .superClass("com.dly.blog.controller.BaseController")
                                .enableRestStyle()
                                .enableFileOverride()

                                .mapperBuilder()
                                .enableFileOverride()
                )
                //添加自定义文件
                .injectionConfig(builder ->
                        builder.customFile(
                                        new CustomFile
                                                .Builder()
                                                .formatNameFunction(tableInfo ->
                                                        tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "") + "/" + StrUtil.upperFirst(tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "")) + "PageRO")
                                                .fileName(".java")
                                                .templatePath("templates/pageRo.java.vm")
                                                .packageName("ro")
                                                .filePath(StrUtil.format("./{}/{}/{}/domain", codeGenProperties.getBaseConfig().getProjectName(),
                                                        codeGenProperties.getBaseConfig().getSrc(),
                                                        codeGenProperties.getBaseConfig().getFilePage()))
                                                .enableFileOverride()
                                                .build())
                                .customFile(
                                        new CustomFile
                                                .Builder()
                                                .formatNameFunction(tableInfo ->
                                                        tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "") + "/" + StrUtil.upperFirst(tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "")) + "AddRO")
                                                .fileName(".java")
                                                .templatePath("templates/addRo.java.vm")
                                                .packageName("ro")
                                                .filePath(StrUtil.format("./{}/{}/{}/domain", codeGenProperties.getBaseConfig().getProjectName(),
                                                        codeGenProperties.getBaseConfig().getSrc(),
                                                        codeGenProperties.getBaseConfig().getFilePage()))
                                                .enableFileOverride()
                                                .build())
                                .customFile(
                                        new CustomFile
                                                .Builder()
                                                .formatNameFunction(tableInfo ->
                                                        tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "") + "/" + StrUtil.upperFirst(tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "")) + "EditRO")
                                                .fileName(".java")
                                                .templatePath("templates/editRo.java.vm")
                                                .packageName("ro")
                                                .filePath(StrUtil.format("./{}/{}/{}/domain", codeGenProperties.getBaseConfig().getProjectName(),
                                                        codeGenProperties.getBaseConfig().getSrc(),
                                                        codeGenProperties.getBaseConfig().getFilePage()))
                                                .enableFileOverride()
                                                .build())
                                .customFile(
                                        new CustomFile
                                                .Builder()
                                                .formatNameFunction(tableInfo ->
                                                        tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "") + "/" + StrUtil.upperFirst(tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "")) + "VO")
                                                .fileName(".java")
                                                .templatePath("templates/vo.java.vm")
                                                .packageName("vo")
                                                .filePath(StrUtil.format("./{}/{}/{}/domain", codeGenProperties.getBaseConfig().getProjectName(),
                                                        codeGenProperties.getBaseConfig().getSrc(),
                                                        codeGenProperties.getBaseConfig().getFilePage()))
                                                .enableFileOverride()
                                                .build())
                                .customFile(
                                        new CustomFile
                                                .Builder()
                                                .formatNameFunction(tableInfo -> codeGenProperties.getBaseConfig().getBaseUrl() + "/" +
                                                        tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "") + "/" + tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), ""))
                                                .fileName(".ts")
                                                .templatePath("templates/index.ts.vm")
                                                .filePath(codeGenProperties.getBaseConfig().getFountApiPath())
                                                .enableFileOverride()
                                                .build())
                                .customFile(
                                        new CustomFile
                                                .Builder()
                                                .formatNameFunction(tableInfo -> codeGenProperties.getBaseConfig().getBaseUrl() + "/" +
                                                        tableInfo.getName().replaceAll(codeGenProperties.getBaseConfig().getTablePrefix(), "") + "/" + "api")
                                                .fileName(".ts")
                                                .templatePath("templates/api.ts.vm")
                                                .filePath(codeGenProperties.getBaseConfig().getFountApiPath())
                                                .enableFileOverride()
                                                .build())
                                //一些自定义的字段
                                .beforeOutputFile((t, m) -> {
                                    m.put("baseUrl", codeGenProperties.getBaseConfig().getBaseUrl());
                                })
                )
                .templateConfig(builder -> builder
                        .controller("templates/controller.java")
                        .entity("templates/entity.java")
                        .service("templates/service.java")
                        .serviceImpl("templates/serviceImpl.java")
                        .mapper("templates/mapper.java")
                        .xml("templates/mapper.xml")
                )
                .templateEngine(new VelocityTemplateEngine()).execute();
        SpringApplication.exit(SpringUtil.getApplicationContext());
    }
}
